const fs = require("fs")
const esprima = require("esprima")
const estraverse = require("estraverse")
const escodegen = require("escodegen")
const iconv = require("iconv-lite")
const base_ast = require("../../tools/es_ast_tool");
// require("./base_op");
const {is_ueq_strict,IndexOf1,Substr1,is_in,bitwise_not,mul,is_lg,div,left_shift,bitwise_or,is_ueq_nostrict,Opposite,is_lte,is_lt,is_instanceof,logical_neg,is_eq_strict,add,Length1,VoidVar,mod,is_eq_nostrict,right_shift,bitwise_and,sub,is_lge,CharCodeAt1,bitwise_eor} = require("./base_op");
const es_tool = require("../../tools/es_ast_tool");


/*
重新排序switchcase
将case按照正常顺序重组
 */
function resort_switchcase_tool2(ast, discrim, sort_values) {
    var case_nodes = [];
    for (let i = 0; i < sort_values.length; i++) {
        var itemList = sort_values[i];
        console.log("item:" + itemList);
        var case_code = `if(${itemList[0]} === ${discrim}){\n`;
        for (let j = 0; j < itemList.length; j++) {
            var case_j = itemList[j];
            var new_node = base_ast.get_by_discrim(ast, case_j);
            if (new_node === null) {
                console.log(case_j);
                continue
            }
            case_code += new_node;
        }
        case_code += "}";
        case_nodes.push(case_code);
    }
    //获取default 的块并加到代码最后
    new_node = base_ast.get_by_discrim(ast, null);
    if (new_node !== null) {
        case_nodes.push(new_node);
    }
    // console.log(case_nodes);
    var new_code = "function A(){";
    for (let c = 0; c < case_nodes.length; c++) {
        var code = case_nodes[c];
        if (c === case_nodes.length - 1) {
            new_code += code + "}\n\n";
        } else {
            new_code += code + "else\n\n";
        }

    }
    return new_code;
    // fs.writeFile(save_file, new_code, (err) => {
    // });
}

/*
将每一条路径进行合并
 */
function getadjacencyList(edges) {
    const mergePaths = (paths, edge) => {
        const [start, end] = edge;
        let mergedPath = null;
        let mergedIndex = -1;

        for (let i = 0; i < paths.length; i++) {
            const path = paths[i];
            if (path[path.length - 1] === start) {
                path.push(end);
                mergedPath = path;
                mergedIndex = i;
                break;
            } else if (path[0] === end) {
                path.unshift(start);
                mergedPath = path;
                mergedIndex = i;
                break;
            }
        }

        if (!mergedPath) {
            paths.push([...edge]);
        } else {
            for (let i = 0; i < paths.length; i++) {
                if (i !== mergedIndex) {
                    const path = paths[i];
                    if (mergedPath[mergedPath.length - 1] === path[0]) {
                        mergedPath.push(...path.slice(1));
                        paths.splice(i, 1);
                        break;
                    } else if (mergedPath[0] === path[path.length - 1]) {
                        mergedPath.unshift(...path.slice(0, -1));
                        paths.splice(i, 1);
                        break;
                    }
                }
            }
        }
    };

    const createPaths = (edges) => {
        const paths = [];
        edges.forEach(edge => mergePaths(paths, edge));
        return paths;
    };

    const paths = createPaths(edges);

    //[ 48, 501, 487 ]
    // [ 20, 402, 593, 262 ]
    // [ 15, 279, 341, 486, 487 ]
    paths.forEach(path => console.log(path));
    return paths;
}

/*
解密字符串1

通过hook 获取到以下解密的字符串对象
sx_obj = {"Sx.MN":"1","Sx.CN":"0"}
de_func = "Sx"
 */
function de_str1(ast, sx_obj, de_func) {
    estraverse.replace(ast, {
        enter(node, parent) {
            if (node.type === "CallExpression" && node.callee && node.callee.type === "MemberExpression") {
                if (node.callee.object && node.callee.object.type === "Identifier" && node.callee.object.name === de_func) {
                    if (node.callee.property && node.callee.property.type === "Identifier") {
                        var func_name = de_func + "." + node.callee.property.name;
                        if (sx_obj.hasOwnProperty(func_name)) {
                            var code = escodegen.generate(node);
                            var val = sx_obj[func_name];
                            console.log(code + " = " + val);
                            return {
                                type: esprima.Syntax.Literal,
                                value: val,
                                raw: val.toString()
                            }
                        }
                    }
                    if (node.callee.property && node.callee.property.type === "Literal") {
                        var func_name = de_func + "." + node.callee.property.value;
                        console.log(func_name);
                        if (sx_obj.hasOwnProperty(func_name)) {
                            var code = escodegen.generate(node);
                            var val = sx_obj[func_name];
                            console.log(code + " = " + val);
                            return {
                                type: esprima.Syntax.Literal,
                                value: val,
                                raw: val.toString()
                            }
                        }
                    }

                }
                if (node.callee.object && node.callee.object.type === "MemberExpression") {
                    if (node.callee.object.object && node.callee.object.object.type === "Identifier" && node.callee.object.property && node.callee.object.property.type === "Identifier") {
                        if (node.callee.property && node.callee.property.type === "Identifier" && (node.callee.property.name === "call" || node.callee.property.name === "apply")) {
                            var func_name = de_func + "." + node.callee.object.property.name;
                            if (sx_obj.hasOwnProperty(func_name)) {
                                var code = escodegen.generate(node);
                                var val = sx_obj[func_name];
                                console.log(code + " = " + val);
                                return {
                                    type: esprima.Syntax.Literal,
                                    value: val,
                                    raw: val.toString()
                                }
                            }
                        }
                    }

                }
                // if(node.callee.object())
            }
        }
    })
}

/*
在解密函数的地方插入hook代码 记录解密值
de_func_name = St
 */
function insert_hook_destr(ast, de_func_name) {
    estraverse.replace(ast, {
        enter(node, parent) {
            if (parent.type === "BlockStatement" && node.type === "ExpressionStatement") {
                if (node.expression && node.expression.type === "AssignmentExpression") {
                    if (node.expression.left && node.expression.left.type === "MemberExpression") {
                        if (node.expression.left.object && node.expression.left.object.type === "Identifier" && node.expression.left.object.name === de_func_name) {
                            if (node.expression.right && node.expression.right.type === "FunctionExpression") {
                                var right_node = node.expression.right;
                                var left_node = node.expression.left;
                                if (right_node.body && right_node.body.type === "BlockStatement") {
                                    if (right_node.body.body && right_node.body.body.length === 1) {
                                        var code = escodegen.generate(node);
                                        console.log(code);
                                        var dec_func1 = left_node.property.name;
                                        var return_var = right_node.body.body[0].argument.name;
                                        const index = parent.body.indexOf(node);
                                        var newCode = `g_de_map.set('${de_func_name}.' + ${dec_func1}, ${return_var});`
                                        var newast = esprima.parse(newCode);
                                        var newNode = newast.body[0];
                                        parent.body.splice(index, 0, newNode);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    });
}

/*
插入 解密字符串的hook 代码
 */
function insert_hook_destrV2_5(ast, de_map){
    estraverse.replace(ast,{
        enter(node, parent){
            if (parent.type === "BlockStatement" && node.type === "ExpressionStatement"){
                if (node.expression && node.expression.type === "AssignmentExpression"){
                    if(node.expression.left&&node.expression.right){
                        var right_node = node.expression.right;
                        var left_node = node.expression.left;
                        if(left_node.type==="MemberExpression"&&right_node.type==="FunctionExpression"){
                            if(left_node.object&&left_node.object.type==="CallExpression"&&left_node.property&&left_node.property.type==="Identifier"&&left_node.object.callee&&left_node.object.callee.type==="Identifier"){
                                if(de_map.has(left_node.object.callee.name)){
                                    if(right_node.body&&right_node.body.type==="BlockStatement"&&right_node.body.body&&right_node.body.body.length===1){
                                        if(right_node.body.body[0].type==="ReturnStatement"&&right_node.body.body[0].argument){
                                            var code = escodegen.generate(node);
                                            console.log(code);
                                            var dec_func1 = left_node.property.name;
                                            var return_var = right_node.body.body[0].argument.name;
                                            const index = parent.body.indexOf(node);
                                            var newCode = `g_de_map.set('${left_node.object.callee.name}.' + ${dec_func1}, ${return_var});`
                                            var newast = esprima.parse(newCode);
                                            var newNode = newast.body[0];
                                            parent.body.splice(index, 0, newNode);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    // var right_node = node.expression.right;
                    // var left_node = node.expression.left;
                    // if(node.left&&node.right&&node.left.type==="MemberExpression"&&node.right.type==="FunctionExpression"&&node.left.object&&node.left.object.type==="CallExpression"){
                    //
                    // }
                }
            }
        }
    })
}

/*
查找一个长度为40-60的整数数组，它是由字符串数组解密得来。
已经出现过的值: 47, 50
 */
function find_arr_50(ast) {
    var result = "";
    estraverse.traverse(ast, {
        enter(node, parent) {
            if (node.type === "AssignmentExpression" && node.operator === "=" && node.left && node.right) {
                if (node.left.type === "Identifier" && node.right.type === "CallExpression") {
                    if (node.right.arguments && node.right.arguments.length === 2) {
                        var node1 = node.right.arguments[0];
                        var node2 = node.right.arguments[1];
                        if (node1.type === "Literal" && node2.type === "ArrayExpression") {
                            if (node2.elements && node2.elements.length === 2) {
                                var node3 = node2.elements[0];
                                var node4 = node2.elements[1];
                                if (node3.type === "ArrayExpression" && node4.type === "CallExpression") {
                                    var ele = node3.elements;
                                    var count = 0;
                                    for (let i = 0; i < ele.length; i++) {
                                        if (ele[i].type === "Literal") {
                                            count += 1;
                                        }
                                    }
                                    if (count === ele.length && count <= 60 && count >= 40) {
                                        result = node.left.name;
                                        console.log("arr_50_name:", result);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    });
    return result;
}

/*
查找保存sensor_data 数组的明文的 数组变量名
根据数组大小=58的特征来确定
 */
function find_andhook_sensor_arr(ast) {
    var result = new Map();
    var sensor_arr = "";
    var arr_50 = find_arr_50(ast);
    estraverse.traverse(ast, {
        enter(node, parent) {
            if (node.type === "ExpressionStatement" && node.expression && node.expression.right && node.expression.right.type === "ArrayExpression" && node.expression.right.elements && node.expression.right.elements.length === 56) {
                for (let i = 0; i < node.expression.right.elements.length; i++) {
                    var nodei = node.expression.right.elements[i];
                    if (nodei.type === "Identifier") {
                        result.set(node.expression.right.elements[i].name, "sensor_arg" + (i + 1));
                    }
                }
                sensor_arr = node.expression.left.name;
                console.log(sensor_arr);
                result.set(sensor_arr, "sensor_arr");
                const index = parent.body.indexOf(node);
                var newCode = `
                    console.log("sensor_arr:", ${sensor_arr});
                    MapStr(g_de_map);
                    console.log("arr_50:", ${arr_50});
                `;
                var newast = esprima.parse(newCode);
                var newNode = newast.body[0];
                parent.body.splice(index + 1, 0, newNode);
                newNode = newast.body[1];
                parent.body.splice(index + 1, 0, newNode);
                newNode = newast.body[2];
                parent.body.splice(index + 1, 0, newNode);
            }

        }
    });
    base_ast.MapStr(result);
    return result;
}

// 查找ast中的 Identifier 变量并返回一个list
function find_subvar_by_node(ast) {
    var result = [];
    estraverse.traverse(ast, {
        enter(node, parent) {
            if (node.type === "Identifier") {
                if (node.name.length <= 3) {
                    result.push(node.name);
                }
            }
        }
    })
    return result;
}

function getIsBraveVar(sub_ast) {
    var result = "";
    estraverse.traverse(sub_ast, {
        enter(node, parent) {
            if (node.type === "AssignmentExpression" && node.left && node.right && node.right.type === "ConditionalExpression") {
                if (node.right.alternate && node.right.alternate.type === "Literal" && node.right.alternate.value === 0) {
                    //S8 = I8 ? 1 : 0;
                    if (node.right.consequent.type === "Literal" && node.right.consequent.value === 1) {
                        result = node.left.name;
                    } else {
                        if (node.right.consequent.type === "MemberExpression") {
                            result = node.left.name;
                        }
                        //S8 = I8 ? Cz[3] : 0;
                    }
                }
            }
        }
    });
    return result;
}

function getArg26_12_1var(sub_ast) {
    var result = "";
    estraverse.traverse(sub_ast, {
        enter(node, parent) {
            if (node.type === "CallExpression" && node.callee && node.callee.name === "div" && node.arguments && node.arguments.length === 2 && node.arguments[0].type === "Identifier") {
                result = node.arguments[0].name;
            }
        }
    });
    return result;
}

function getMouseVars(sub_ast) {
    var result = [];
    estraverse.traverse(sub_ast, {
        enter(node, parent) {
            if (node.type === "ExpressionStatement" && node.expression && node.expression.type === "AssignmentExpression" && node.expression.left && node.expression.left.type === "Identifier") {
                var code = escodegen.generate(node);
                if (code.indexOf("add(add(add(add(add") !== -1) {
                    result[0] = node.expression.left.name;
                    var i = parent.body.indexOf(node);
                    var nodei = parent.body[i + 1];
                    if (nodei.type === "ExpressionStatement" && nodei.expression && nodei.expression.type === "AssignmentExpression" && nodei.expression.operator === "+=" && nodei.expression.left) {
                        result[1] = nodei.expression.left.name;
                    }
                }
            }
            if (node.type === "ExpressionStatement" && node.expression && node.expression.type === "UpdateExpression" && node.expression.operator === "++") {
                if (node.expression.argument && node.expression.argument.type === "Identifier") {
                    result[2] = node.expression.argument.name;
                }
            }
        }
    })
    return result;
}

function getPointerVars(sub_ast) {
    var result = [];
    estraverse.traverse(sub_ast, {
        enter(node, parent) {
            if (node.type === "ExpressionStatement" && node.expression && node.expression.type === "UpdateExpression" && node.expression.operator === "++") {
                if (node.expression.argument && node.expression.argument.type === "Identifier") {
                    result[0] = node.expression.argument.name;
                }
            }
        }
    })
    return result;
}

/*
查找某些固定变量，关键变量重命名
window 全局对象；解密函数 栈列表变量；
var sensor_arg42 = ''['concat'](arg42_1, ',')['concat'](arg42_2, ',')['concat'](arg42_3);
var sensor_arg44 = ''['concat'](arg44_1, ',')['concat'](arg44_2, ',')['concat'](arg44_3, ',')['concat'](arg44_4, ',,,,,,')['concat'](arg44_5, ',,,')['concat'](arg44_6, ',')['concat'](arg44_7);
var sensor_arg46 = ''['concat'](arg46_1, ',,,')['concat'](arg46_2, ',')['concat'](arg46_3);
 */
function find_global_vars(ast) {
    var mapObjsResult1 = new Map();  // 逆向映射表
    var setFuncsResult2 = new Set();   // 逆向函数名 集合
    var setVarsResult3 = new Set();     // 逆向变量名 集合
    var flag_gwin = false;
    var flag_jsHeapSize = false;
    var flag_plugin = false;
    var flag_sessionStorage = false;
    var flag_localStorage = false;
    var flag_noheadBrowser = false;
    var flag_webdriver2 = false;
    var flag_navigatorProduct = false;
    var flag_appleWebKit = false;
    var flag_PluginFinger = false;
    var flag_NavigatorWebdriver = false;
    var flag_DocumentCookie = false;
    var flag_autocomplete = false;
    var flag_SignStr = false;
    var flag_fpValStr = false;
    var flag_SetVoicesDec = false;
    var flag_CallSetVoicesDec = false;
    var flag_SignStrToArr = false;
    var flag_GetArrToHexStr = false;
    var flag_PermissinInfo = false;
    var flag_brave = false;
    var flag_init_args = false;
    var flag_apr_init_arr = false;
    var flag_sjs_r_obj = false;
    var flag_2n_calc = false;
    var flag_call_2n_calc = false;
    var flag_webGlRender = false;
    var flag_webGlHardware = false;
    var flag_Trident = false;
    var flag_SetArg424344 = false;
    var flag_timeSign = false;
    var flag_signTotVel = false;
    var flag_dealAbck4Arr = false;
    var flag_getSensorSegment = false;
    var flag_DecUtilsSub1 = false;
    var flag_bm_sz_deal = false;
    var flag_MouseTrack = false;
    var flag_PointerClickNum = false;
    var flag_deviceMemory = false;
    var flag_hardwareConcurrency = false;
    var flag_webGLVendor = false;
    var flag_IsPlugins = false;
    var flag_PluginsDeviceMemoryArr = false;
    var flag_getSensorData = false;
    var flag_mouseMoveDataSign = false;
    var flag_randomInt = false;
    var flag_ArrayLogic = false;
    var mouse_same_map = new Map();
    estraverse.traverse(ast, {
        enter(node, parent) {
            // 查找到window 全局变量
            if (!flag_gwin && node.type === "AssignmentExpression" && node.right && node.right.type === "Identifier" && node.right.name === "window") {
                if (node.left) {
                    var code = escodegen.generate(node);
                    console.log(code);
                    mapObjsResult1.set(node.left.name, "g_win");
                    // setVarsResult3.add("g_win");
                    flag_gwin = true;
                }
            }
            // 查找到 getDateNow, getUA, getTimezoneOffset, isRTCPeerConnection, isIndexedDB 函数
            if (node.type === "FunctionDeclaration" && node.id && node.body && node.body.type === "BlockStatement" && node.body.body) {
                var bodys = node.body.body;
                if (bodys.length === 5) {
                    // var code = escodegen.generate(node);
                    // console.log(code);
                    var body1_code = escodegen.generate(bodys[0]);
                    var body3_code = escodegen.generate(bodys[2]);
                    var body4_code = escodegen.generate(bodys[3]);
                    if (body1_code.indexOf("push") !== -1 && body4_code.indexOf("pop") !== -1) {
                        mapObjsResult1.set(bodys[0].expression.callee.object.name, "stack");
                        // setVarsResult3.add("stack");
                    }
                    if (body3_code.indexOf("Date") !== -1 && body3_code.indexOf("now") !== -1) {
                        mapObjsResult1.set(node.id.name, "getDateNow");
                        setFuncsResult2.add("getDateNow");
                    }
                    if (body3_code.indexOf("window") !== -1 && body3_code.indexOf("navigator") !== -1 && body3_code.indexOf("userAgent") !== -1) {
                        mapObjsResult1.set(node.id.name, "getUA");
                        setFuncsResult2.add("getUA");
                    }
                    if (body3_code.indexOf("Date") !== -1 && body3_code.indexOf("getTimezoneOffset") !== -1) {
                        mapObjsResult1.set(node.id.name, "getTimezoneOffset");
                        setFuncsResult2.add("getTimezoneOffset");
                    }
                    if (body3_code.indexOf("RTCPeerConnection") !== -1 && body3_code.indexOf("window") !== -1) {
                        mapObjsResult1.set(node.id.name, "isRTCPeerConnection");
                        setFuncsResult2.add("isRTCPeerConnection");
                    }
                    if (body3_code.indexOf("indexedDB") !== -1 && body3_code.indexOf("window") !== -1) {
                        mapObjsResult1.set(node.id.name, "isIndexedDB");
                        setFuncsResult2.add("isIndexedDB");
                    }
                }
            }
            // 查找user-agent 相关参数生产函数 sensor_arg2
            if (node.type === "VariableDeclarator" && node.id && node.id.name === "sensor_arg2") {
                if (node.init && node.init.arguments && node.init.arguments.length === 2) {
                    var node1 = node.init.arguments[1];
                    if (node1.type === "ArrayExpression" && node1.elements && node1.elements.length === 2) {
                        var node2 = node1.elements[0];
                        if (node2.type === "Identifier") {
                            mapObjsResult1.set(node2.name, "getUAEncStr");
                            setFuncsResult2.add("getUAEncStr");
                        }
                    }
                }
            }
            //查找 arg42_1 生产函数
            if (node.type === "AssignmentExpression" && node.left && node.left.type === "Identifier" && node.left.name === "arg42_1") {
                if (node.right && node.right.type === "CallExpression" && node.right.callee && node.right.callee.type === "Identifier") {
                    mapObjsResult1.set(node.right.callee.name, "getSubArg42_1");
                    setFuncsResult2.add("getSubArg42_1");
                }
            }
            //查找 arg44_2 生产函数
            if (node.type === "AssignmentExpression" && node.left && node.left.type === "Identifier" && node.left.name === "arg44_2") {
                if (node.right && node.right.type === "CallExpression" && node.right.callee && node.right.callee.type === "Identifier") {
                    mapObjsResult1.set(node.right.callee.name, "getSubArg44_2");
                    setFuncsResult2.add("getSubArg44_2");
                }
            }
            // sensor_arg26 的子项
            if (node.type === "VariableDeclarator" && node.id && node.id.name === "sensor_arg26") {
                if (node.init && node.init.type === "CallExpression" && node.init.callee && node.init.callee.type === "MemberExpression" && node.init.callee.object && node.init.callee.object.type === "ArrayExpression") {
                    var nodes = node.init.callee.object.elements;
                    for (let i = 0; i < nodes.length; i++) {
                        var nodei = nodes[i];
                        if (nodei.type === "Identifier") {
                            mapObjsResult1.set(nodei.name, `arg26_${i + 1}`);
                            // setVarsResult3.add(`arg26_${i + 1}`);
                        }
                        if (nodei.type === "CallExpression" && nodei.arguments && nodei.arguments.length === 2) {
                            if (nodei.arguments[0].type === "Identifier" && (nodei.arguments[1].type === "Literal" || nodei.arguments[1].type === "MemberExpression")) {
                                mapObjsResult1.set(nodei.arguments[0].name, `arg26_${i + 1}`);
                                // setVarsResult3.add(`arg26_${i + 1}`);
                            }
                        }
                    }
                }
            }
            // arg26_12 = g_win['parseInt'](div(YD, wl[50]), 10);
            if (node.type === "AssignmentExpression" && node.left && node.right && node.left.name === "arg26_12") {
                var code = escodegen.generate(node);
                if (code.indexOf("parseInt") !== -1 && code.indexOf("div") !== -1) {
                    var arg26_12_1 = getArg26_12_1var(node);
                    if (arg26_12_1 !== "") {
                        mapObjsResult1.set(arg26_12_1, "arg26_12_1");
                        // setVarsResult3.add("arg26_12_1");
                    }
                }
            }

            //sensor_arr sensor_arg60 变量
            if (node.type === "CallExpression" && node.callee && node.callee.type === "MemberExpression" && node.callee.object && node.callee.object.type === "Identifier") {
                if (node.callee.object.name === "sensor_arr" && node.callee.property && node.callee.property.type === "Literal" && node.callee.property.value === "push") {
                    if (node.arguments && node.arguments.length === 2) {
                        var node1 = node.arguments[0];
                        var node2 = node.arguments[1];
                        if (node1.type === "Literal" && node1.value === "-129" && node2.type === "Identifier") {
                            mapObjsResult1.set(node2.name, "sensor_arg60");
                            // setVarsResult3.add("sensor_arg60");
                        }
                    }
                }
            }
            //sensor_arg60 的拼接变量重命名
            if (node.type === "VariableDeclarator" && node.id && node.id.type === "Identifier" && node.id.name === "sensor_arg60") {
                var arg60_sub_vals_list = find_subvar_by_node(node);
                console.log("arg60_sub_vals_list:" + arg60_sub_vals_list);
                for (let i = 0; i < arg60_sub_vals_list.length; i++) {
                    if (arg60_sub_vals_list[i].length <= 3) {
                        mapObjsResult1.set(arg60_sub_vals_list[i], `arg60_${i + 1}`);
                        setVarsResult3.add(`arg60_${i + 1}`);
                    }
                }
            }

            //sensor_arg42 的拼接变量重命名
            if (node.type === "VariableDeclarator" && node.id && node.id.type === "Identifier" && node.id.name === "sensor_arg42") {
                var arg42_sub_vals_list = find_subvar_by_node(node);
                console.log("arg42_sub_vals_list:" + arg42_sub_vals_list);
                for (let i = 0; i < arg42_sub_vals_list.length; i++) {
                    if (arg42_sub_vals_list[i].length <= 3) {
                        mapObjsResult1.set(arg42_sub_vals_list[i], `arg42_${i + 1}`);
                        setVarsResult3.add(`arg42_${i + 1}`);
                    }
                }
                setVarsResult3.add("sensor_arg40");
                setVarsResult3.add("sensor_arg4");
                setVarsResult3.add("sensor_arg30");
                setVarsResult3.add("sensor_arg56");
            }

            //sensor_arg44 的拼接变量重命名
            if (node.type === "VariableDeclarator" && node.id && node.id.type === "Identifier" && node.id.name === "sensor_arg44") {
                var arg44_sub_vals_list = find_subvar_by_node(node);
                console.log("arg44_sub_vals_list:" + arg44_sub_vals_list);
                for (let i = 0; i < arg44_sub_vals_list.length; i++) {
                    if (arg44_sub_vals_list[i].length <= 3) {
                        mapObjsResult1.set(arg44_sub_vals_list[i], `arg44_${i + 1}`);
                        setVarsResult3.add(`arg44_${i + 1}`);
                    }
                }
            }

            // arg44_1 = ''['concat'](getJsHeapInfo(), ',')['concat'](xA);
            // arg44_1 参与计算的变量重命名
            if (node.type === "AssignmentExpression" && node.left && node.left.name === "arg44_1") {
                if (node.right && node.right.arguments && node.right.arguments.length === 1) {
                    if (node.right.arguments[0].type === "Identifier") {
                        mapObjsResult1.set(node.right.arguments[0].name, "arg44_1_1");
                        setVarsResult3.add("arg44_1_1");
                    }
                }
            }

            //sensor_arg24 的拼接变量重命名
            if (node.type === "VariableDeclarator" && node.id && node.id.type === "Identifier" && node.id.name === "sensor_arg24") {
                var arg24_sub_vals_list = find_subvar_by_node(node);
                console.log("arg24_sub_vals_list:" + arg24_sub_vals_list);
                for (let i = 0; i < arg24_sub_vals_list.length; i++) {
                    if (arg24_sub_vals_list[i].length <= 3) {
                        mapObjsResult1.set(arg24_sub_vals_list[i], `arg24_${i + 1}`);
                        setVarsResult3.add(`arg24_${i + 1}`);
                    }
                }
            }

            //sensor_arg46 的拼接变量重命名
            if (node.type === "VariableDeclarator" && node.id && node.id.type === "Identifier" && node.id.name === "sensor_arg46") {
                var arg46_sub_vals_list = find_subvar_by_node(node);
                console.log("arg46_sub_vals_list:" + arg46_sub_vals_list);
                for (let i = 0; i < arg46_sub_vals_list.length; i++) {
                    if (arg46_sub_vals_list[i].length <= 3) {
                        mapObjsResult1.set(arg46_sub_vals_list[i], `arg46_${i + 1}`);
                        setVarsResult3.add(`arg46_${i + 1}`);
                    }
                }
            }

            //字符串处理函数 把第一个字符串中的字母原样保存，数字进行一定处理  ZHr('0a46G5m17Vrp4o4c', 'afSbep8yjnZUjq3aL010jO15Sawj2VZfdYK8uY90uxq')
            if (node.type === "CallExpression" && node.callee && node.callee.type === "Identifier" && node.arguments && node.arguments.length === 2) {
                if (node.arguments[0].type === "Literal" && node.arguments[0].value === "0a46G5m17Vrp4o4c") {
                    if (node.callee.name.length <= 3) {
                        mapObjsResult1.set(node.callee.name, "strDecUtils1");
                        setFuncsResult2.add("strDecUtils1");
                    }
                }
            }

            //bm_sz
            if (node.type === "VariableDeclarator" && node.id && node.id.type === "Identifier" && node.init && node.init.value === "bm_sz") {
                mapObjsResult1.set(node.id.name, "cookie_bm_sz");
                setVarsResult3.add("cookie_bm_sz");
            }

            //_abck
            if (node.type === "VariableDeclarator" && node.id && node.id.type === "Identifier" && node.init && node.init.value === "_abck") {
                mapObjsResult1.set(node.id.name, "cookie_abck");
                setVarsResult3.add("cookie_abck");
            }

            // abcdefghijklmnopaqrstuvxyzABCDEFGHIJKLMNOPAQRSTUVXYZ
            if (node.type === "AssignmentExpression" && node.left && node.right && node.left.type === "Identifier" && node.right.type === "Literal") {
                if (node.right.raw.indexOf("abcdefghijklmnopaqrstuvxyzABCDEFGHIJKLMNOPAQRSTUVXYZ") !== -1) {
                    mapObjsResult1.set(node.left.name, "ABCXYZ");
                    setVarsResult3.add("ABCXYZ");
                }
            }

            // var XR = ''['concat']('UAu0LTJ2TKcwhgB28mDjmA==');
            if(node.type==="VariableDeclarator"&&node.id&&node.init&&node.id.type==="Identifier"&&node.init.type==="CallExpression"){
                if(node.init.callee&&node.init.arguments&&node.init.callee.type==="MemberExpression"&&node.init.arguments.length===1){
                    if(node.init.callee.object&&node.init.callee.property&&node.init.callee.object.value===""&&node.init.callee.property.value==="concat"){
                        if(node.init.arguments[0].type==="Literal"&&node.init.arguments[0].value.length===24){
                            mapObjsResult1.set(node.id.name, "const_str24");
                            setVarsResult3.add("const_str24");
                        }
                    }
                }
            }
        },
        leave(node, parent) {
            if (!flag_jsHeapSize) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("jsHeapSizeLimit") !== -1) {
                            mapObjsResult1.set(node.id.name, "getJsHeapInfo");
                            setFuncsResult2.add("getJsHeapInfo");
                            flag_jsHeapSize = true;
                        }
                    }
                }
            }
            //获取浏览器安装了哪些插件 返回值按照序号来的
            if (!flag_plugin) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("YouTube Plug-in") !== -1) {
                            mapObjsResult1.set(node.id.name, "getPluginInfo");
                            setFuncsResult2.add("getPluginInfo");
                            flag_plugin = true;
                        }
                    }
                }
            }
            // 判断是否支持 sessionStorage
            if (!flag_sessionStorage) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("sessionStorage") !== -1) {
                            mapObjsResult1.set(node.id.name, "isSupportSessionStorage");
                            setFuncsResult2.add("isSupportSessionStorage");
                            flag_sessionStorage = true;
                        }
                    }
                }
            }
            // localStorage
            if (!flag_localStorage) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "");
                        if (code.indexOf("logical_neg(logical_neg(") !== -1 && code.indexOf("[window][localStorage]))") !== -1) {
                            mapObjsResult1.set(node.id.name, "isSupportLocalStorage");
                            setFuncsResult2.add("isSupportLocalStorage");
                            flag_localStorage = true;
                        }
                    }
                }
            }
            // __selenium_unwrapped __phantomas __webdriver_script_fn 检测无头浏览器 按照二进制位进行数据存储
            if (!flag_noheadBrowser) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("__webdriver_script_fn") !== -1) {
                            mapObjsResult1.set(node.id.name, "getNoheadBrowserInfo");
                            setFuncsResult2.add("getNoheadBrowserInfo");
                            flag_noheadBrowser = true;
                        }
                    }
                }
            }
            // webdriver
            if (!flag_webdriver2) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("XPathResult") !== -1 && code.indexOf("webdriver") !== -1 && code.indexOf("selenium") !== -1) {
                            mapObjsResult1.set(node.id.name, "getIsSeleniumArr");
                            setFuncsResult2.add("getIsSeleniumArr");
                            flag_webdriver2 = true;
                        }
                    }
                }
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    var code = escodegen.generate(node);
                    if (code.indexOf("XPathResult") !== -1 && code.indexOf("webdriver") !== -1 && code.indexOf("selenium") !== -1) {
                        mapObjsResult1.set(node.id.name, "getIsSeleniumArr");
                        setFuncsResult2.add("getIsSeleniumArr");
                        flag_webdriver2 = true;
                    }
                }
            }
            //navigator.productSub product 数据
            if (!flag_navigatorProduct) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("productSub") !== -1 && code.indexOf("language") !== -1 && code.indexOf("plugins") !== -1) {
                            mapObjsResult1.set(node.id.name, "getNavigatorProductInfo");
                            setFuncsResult2.add("getNavigatorProductInfo");
                            flag_navigatorProduct = true;
                        }
                    }
                }
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("productSub") !== -1 && code.indexOf("language") !== -1 && code.indexOf("plugins") !== -1) {
                            mapObjsResult1.set(node.id.name, "getNavigatorProductInfo");
                            setFuncsResult2.add("getNavigatorProductInfo");
                            flag_navigatorProduct = true;
                        }
                    }
                }
            }
            // AppleWebKit iPhone|iPad
            if (!flag_appleWebKit) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("iPhone") !== -1 && code.indexOf("iPad") !== -1 && code.indexOf("AppleWebKit") !== -1) {
                            mapObjsResult1.set(node.id.name, "isMobileBrowser");
                            setFuncsResult2.add("isMobileBrowser");
                            flag_appleWebKit = true;
                        }
                    }
                }
            }
            // fpValStr plugin_finger数组
            if (!flag_PluginFinger) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("cookieEnabled") !== -1 && code.indexOf("javaEnabled") !== -1 && code.indexOf("fpValStr") !== -1) {
                            mapObjsResult1.set(node.id.name, "getPluginFingerFPArr");
                            setFuncsResult2.add("getPluginFingerFPArr");
                            flag_PluginFinger = true;
                        }
                    }
                }
            }

            // 判断参数是否是 navigator的webdriver
            if (!flag_NavigatorWebdriver) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "");
                        if (code.indexOf("navigator][webdriver") !== -1 && code.indexOf("selenium") === -1) {
                            mapObjsResult1.set(node.id.name, "isNavigatorWebdriver");
                            setFuncsResult2.add("isNavigatorWebdriver");
                            flag_NavigatorWebdriver = true;
                        }
                    }
                }
            }
            // 获取cookie_by_key
            if (!flag_DocumentCookie) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "");
                        if (code.indexOf("document][cookie][split") !== -1) {
                            mapObjsResult1.set(node.id.name, "getDocumentCookieByKey");
                            setFuncsResult2.add("getDocumentCookieByKey");
                            flag_DocumentCookie = true;
                        }
                    }
                }
            }
            // sensor_arg16 生产函数
            if (!flag_autocomplete) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "");
                        if (code.indexOf("getElementsByTagName") !== -1 && code.indexOf("autocomplete") !== -1) {
                            mapObjsResult1.set(node.id.name, "getHtmlInputElementInfo");
                            setFuncsResult2.add("getHtmlInputElementInfo");
                            flag_autocomplete = true;
                        }
                    }
                }
            }
            // 字符串签名函数，把abck cookie字符串或其它字符串进行签名计算出来一个签名值
            if (!flag_SignStr) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("<128") !== -1 && code.indexOf("charCodeAt") !== -1 && code.indexOf("length") !== -1) {
                            mapObjsResult1.set(node.id.name, "SignDataToInt");
                            setFuncsResult2.add("SignDataToInt");
                            flag_SignStr = true;
                        }
                    }
                }
            }
            /*
            数组fp的变量重命名
            [
                        'fpValStr',
                        '-1',
                        'rVal',
                        '-1',
                        'rCFP',
                        '-1',
                        'td',
                        Opposite(zv[27])
                    ]
             */
            if (!flag_fpValStr) {
                if (node.type === "VariableDeclarator" && node.id && node.init && node.init.type === "CallExpression") {
                    if (node.init.arguments && node.init.arguments.length === 2) {
                        var node2 = node.init.arguments[1];
                        if (node2.type === "ArrayExpression") {
                            var code = escodegen.generate(node2);
                            if (code.indexOf("fpValStr") !== -1 && code.indexOf("rVal") !== -1 && code.indexOf("rCFP") !== -1 && code.indexOf("td") !== -1) {
                                mapObjsResult1.set(node.id.name, "fpValArr");

                                setVarsResult3.add("arg26_19");
                                setVarsResult3.add("arg26_12");
                                setVarsResult3.add("arg26_12_1");
                                setVarsResult3.add("arg26_20");
                                setVarsResult3.add("fpValArr");
                                flag_fpValStr = true;
                            }
                        }
                    }
                }
            }

            // g_win['window']['speechSynthesis']['getVoices']  voiceURI 浏览器声音相关数据 加密 设置 arg60_3 的值
            if (!flag_SetVoicesDec) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("speechSynthesis") !== -1 && code.indexOf("getVoices") !== -1 && code.indexOf("voiceURI") !== -1) {
                            mapObjsResult1.set(node.id.name, "setVoicesDecArg60_3");
                            setFuncsResult2.add("setVoicesDecArg60_3");
                            flag_SetVoicesDec = true;
                        }
                    }
                }
            }

            // 调用 setVoicesDecArg60_3 函数 并设置 声音数据改变 回调函数=setVoicesDecArg60_3
            if (!flag_CallSetVoicesDec) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("speechSynthesis") !== -1 && code.indexOf("getVoices") !== -1 && code.indexOf("onvoiceschanged") !== -1) {
                            mapObjsResult1.set(node.id.name, "callSetVoicesDecArg60_3");
                            setFuncsResult2.add("callSetVoicesDecArg60_3");
                            flag_CallSetVoicesDec = true;
                        }
                    }
                }
            }
            // 将传入的字符串或整数 签名计算称一个32长度的整数数组
            if (!flag_SignStrToArr) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (base_ast.countSubstringSimple(code, "255") >= 30) {
                            mapObjsResult1.set(node.id.name, "SignDataToArr32");
                            setFuncsResult2.add("SignDataToArr32");
                            flag_SignStrToArr = true;
                        }
                    }
                }
            }
            // 将整数数组转换为16进制字符串
            if (!flag_GetArrToHexStr) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("toString](16)[length") !== -1) {
                            mapObjsResult1.set(node.id.name, "GetArrToHexStr");
                            setFuncsResult2.add("GetArrToHexStr");
                            flag_GetArrToHexStr = true;
                        }
                    }
                }
            }
            // permissions 获取权限相关数据
            if (!flag_PermissinInfo) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("permissions") !== -1 && code.indexOf("camera") !== -1 && code.indexOf("clipboard") !== -1 && code.indexOf("prompt") !== -1) {
                            mapObjsResult1.set(node.id.name, "SetPermissinInfoArg40");
                            setFuncsResult2.add("SetPermissinInfoArg40");
                            flag_PermissinInfo = true;
                        }
                    }
                }
            }

            // brave 浏览器检测
            if (!flag_brave) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("navigator][brave") !== -1) {
                            var isBraveVar = getIsBraveVar(node);
                            if (isBraveVar !== "") {
                                mapObjsResult1.set(isBraveVar, "isBrave");
                                setVarsResult3.add("isBrave");
                                setVarsResult3.add("arg26_31");
                                setVarsResult3.add("arg26_33");
                            }
                            mapObjsResult1.set(node.id.name, "setIsBraveBorwser");
                            setFuncsResult2.add("setIsBraveBorwser");
                            flag_brave = true;
                        }
                    }
                }
            }
            // 初始化 args等数据参数
            if (!flag_init_args) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("mouse_move_num=0") !== -1 && code.indexOf("sum_mouse_data=0") !== -1 && code.indexOf("mouse_track=") !== -1) {
                            mapObjsResult1.set(node.id.name, "initSensorArgs");
                            setFuncsResult2.add("initSensorArgs");
                            flag_init_args = true;
                        }
                    }
                }
            }
            // 查找apr 数组
            if (!flag_apr_init_arr) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "CallExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("ajTypeBitmask") !== -1 && code.indexOf("lastAprAutopostTS") !== -1 && code.indexOf("failedAprApCnt") !== -1) {
                            mapObjsResult1.set(node.id.name, "aprArr");
                            setFuncsResult2.add("aprArr");
                            setVarsResult3.add("aprArr");
                            flag_apr_init_arr = true;
                        }
                    }
                }
            }

            //sjs_r func
            if (!flag_sjs_r_obj) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("sjs_r") !== -1 && code.indexOf("constructor") !== -1 && code.indexOf("set") !== -1) {
                            mapObjsResult1.set(node.id.name, "NewObjectSjs_r");
                            setFuncsResult2.add("NewObjectSjs_r");
                            flag_sjs_r_obj = true;
                        }
                    }
                }
            }

            //2n / 2n+1 func
            if (!flag_2n_calc) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("bitwise_and(bitwise_eor(bitwise_eor(right_shift") !== -1) {
                            mapObjsResult1.set(node.id.name, "bitwise_2n_calc");
                            setFuncsResult2.add("bitwise_2n_calc");
                            flag_2n_calc = true;
                        }
                    }
                }
            }

            // call 2n / 2n+1 func
            if (!flag_call_2n_calc) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("bitwise_2n_calc") !== -1 && code.indexOf("1000") !== -1) {
                            mapObjsResult1.set(node.id.name, "mod1000_2n_calc");
                            setFuncsResult2.add("mod1000_2n_calc");
                            flag_call_2n_calc = true;
                        }
                    }
                }
            }

            // WebGLRenderingContext iframe
            if (!flag_webGlRender) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("WebGLRenderingContext") !== -1 && code.indexOf("canvas") !== -1 && code.indexOf("iframe") !== -1) {
                            mapObjsResult1.set(node.id.name, "getWegGlIframeDecInfo");
                            setFuncsResult2.add("getWegGlIframeDecInfo");
                            flag_webGlRender = true;
                        }
                    }
                }
            }

            // WebGL hardware info
            if (!flag_webGlHardware) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("MAX_VERTEX_UNIFORM_VECTORS") !== -1 && code.indexOf("maskedInfo") !== -1) {
                            mapObjsResult1.set(node.id.name, "getWegGlHardwareInfo");
                            setFuncsResult2.add("getWegGlHardwareInfo");
                            flag_webGlHardware = true;
                        }
                    }
                }
            }

            // WebGL hardware info
            if (!flag_Trident) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("Trident/7.0") !== -1 && code.indexOf("iframe") === -1) {
                            mapObjsResult1.set(node.id.name, "getTridentInfo");
                            setFuncsResult2.add("getTridentInfo");
                            flag_Trident = true;
                        }
                    }
                }
            }

            // set arg42 arg43 arg44
            if (!flag_SetArg424344) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("CanvasText") !== -1 && code.indexOf("createElement") !== -1 && code.indexOf("getOwnPropertyDescriptor") !== -1) {
                            mapObjsResult1.set(node.id.name, "setArg42_Arg48");
                            setFuncsResult2.add("setArg42_Arg48");
                            flag_SetArg424344 = true;
                        }
                    }
                }
            }

            // 100000
            if (!flag_timeSign) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("100000") !== -1 && code.indexOf("random") !== -1 && code.indexOf("sqrt") !== -1) {
                            mapObjsResult1.set(node.id.name, "getTimeSign");
                            setFuncsResult2.add("getTimeSign");
                            flag_timeSign = true;
                        }
                    }
                }
            }

            // totVel
            if (!flag_signTotVel) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("100000") !== -1 && code.indexOf("random") !== -1 && code.indexOf("totVel") !== -1) {
                            mapObjsResult1.set(node.id.name, "getTotVelSign");
                            setFuncsResult2.add("getTotVelSign");
                            flag_signTotVel = true;
                        }
                    }
                }
            }

            // 处理abck cookie 按照～分割的第5个值中的数组
            if (!flag_dealAbck4Arr) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("split](~") !== -1 && code.indexOf("split](||") !== -1 && code.indexOf("decodeURIComponent") !== -1) {
                            mapObjsResult1.set(node.id.name, "dealCookieForAbck4Arr");
                            setFuncsResult2.add("dealCookieForAbck4Arr");
                            flag_dealAbck4Arr = true;
                        }
                    }
                }
            }

            // if (node.type === "FunctionDeclaration") {
            //     if (node.id && node.id.type === "Identifier") {
            //         var code = escodegen.generate(node);
            //         code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
            //         if (code.indexOf("split](~") !== -1&&code.indexOf("decodeURIComponent")!==-1) {
            //             // console.log("--func--:",code);
            //             // result.set(node.id.name, "dealAbck4Arr");
            //             // flag_dealAbck4Arr = true;
            //         }
            //     }
            // }

            if (!flag_bm_sz_deal) {
                if (node.type === "FunctionDeclaration") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (code.indexOf("split](~") !== -1 && code.indexOf("decodeURIComponent") !== -1 && code.indexOf("cookie_bm_sz") !== -1) {
                            // console.log("--bm_sz--:",code);
                            mapObjsResult1.set(node.id.name, "dealCookieForBm_sz");
                            setFuncsResult2.add("dealCookieForBm_sz");
                            flag_bm_sz_deal = true;
                            var cookie_8877s = find_cookie_8877(node);
                            if (cookie_8877s.length === 2) {
                                mapObjsResult1.set(cookie_8877s[0], "num_88");
                                mapObjsResult1.set(cookie_8877s[1], "num_77");
                                setVarsResult3.add("num_88");
                                setVarsResult3.add("num_77");
                            }
                        }
                    }
                }
            }

            // sensor_arr segmentation
            if (!flag_getSensorSegment) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        if (code.indexOf("abcdefghijklmnopaqrstuvxyzABCDEFGHIJKLMNOPAQRSTUVXYZ") !== -1 && code.indexOf("random") !== -1 && code.indexOf("floor") !== -1) {
                            mapObjsResult1.set(node.id.name, "getSensorSegment");
                            setFuncsResult2.add("getSensorSegment");
                            flag_getSensorSegment = true;
                        }
                    }
                }
            }

            // 修改3个函数 Array']['isArray
            if (node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier") {
                var code = escodegen.generate(node);
                code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                if (code.indexOf("Array][isArray") !== -1) {
                    if (base_ast.countSubstringSimple(code, "Array\\]\\[from") === 2) {
                        mapObjsResult1.set(node.id.name, "GetArrayOrStringFrom2");
                        setFuncsResult2.add("GetArrayOrStringFrom2");
                    } else if (base_ast.countSubstringSimple(code, "Array\\]\\[from") === 1) {
                        mapObjsResult1.set(node.id.name, "GetArrayOrStringSameTwo");
                        setFuncsResult2.add("GetArrayOrStringSameTwo");
                    }
                }
            }

            // DecUtilsSub1 计算字符串加密的辅助小函数
            if (!flag_DecUtilsSub1) {
                if (node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression") {
                    if (node.id && node.id.type === "Identifier") {
                        var code = escodegen.generate(node);
                        code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                        if (base_ast.countSubstringSimple(code, "is_lg") === 2 && base_ast.countSubstringSimple(code, "is_lte") === 1 &&
                            base_ast.countSubstringSimple(code, "sub") === 2 && base_ast.countSubstringSimple(code, "mod") === 1) {
                            mapObjsResult1.set(node.id.name, "DecUtilsSub1");
                            setFuncsResult2.add("DecUtilsSub1");
                            flag_DecUtilsSub1 = true;
                        }
                    }
                }
            }

            //  find mouse_track
            if (!flag_MouseTrack) {
                if (node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier") {
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if (code.indexOf("pageY") !== -1 && code.indexOf("toElement") !== -1) {
                        var mouse_vars = getMouseVars(node);
                        if (mouse_vars.length === 3) {
                            mapObjsResult1.set(mouse_vars[0], "sum_mouse_data");    // 鼠标相关数据值总和
                            mapObjsResult1.set(mouse_vars[1], "mouse_track");        // 鼠标轨迹数据 包含移动次数; 鼠标的事件类型1--移动 3--点击; 时间戳; 鼠标位置信息
                            mapObjsResult1.set(mouse_vars[2], "mouse_move_num");     // 鼠标移动次数--第几次，当移动/点击一次就加1
                            mouse_same_map.set("mouse_track", mouse_vars[1]);
                            mouse_same_map.set("sum_mouse_data", mouse_vars[0]);
                            setVarsResult3.add("sum_mouse_data");
                            setVarsResult3.add("mouse_track");
                            setVarsResult3.add("mouse_move_num");
                            flag_MouseTrack = true;
                        }
                    }
                }
            }

            // find pointer_click_num
            if (!flag_PointerClickNum) {
                if (node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier") {
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if (code.indexOf("pageY") !== -1 && code.indexOf("pointerType") !== -1) {
                        var pointerVars = getPointerVars(node);
                        if (pointerVars.length === 1) {
                            mapObjsResult1.set(pointerVars[0], "pointer_click_num");    // 鼠标点击/触摸屏点击数
                            setVarsResult3.add("pointer_click_num");
                            mouse_same_map.set("pointer_click_num", pointerVars[0]);
                            flag_PointerClickNum = true;
                        }
                    }
                }
            }

            // deviceMemory
            if(!flag_deviceMemory){
                if (node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier"){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("navigator][deviceMemory")!==-1){
                        mapObjsResult1.set(node.id.name, "getDeviceMemory");
                        setFuncsResult2.add("getDeviceMemory");
                        flag_deviceMemory = true;
                    }
                }
            }

            // hardwareConcurrency
            if(!flag_hardwareConcurrency){
                if(node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier"){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("navigator][hardwareConcurrency")!==-1&&code.indexOf("webkitGetGamepads")===-1){
                        mapObjsResult1.set(node.id.name, "getHardwareConcurrency");
                        setFuncsResult2.add("getHardwareConcurrency");
                        flag_hardwareConcurrency = true;
                    }
                }
            }

            //webGLVendor
            if(!flag_webGLVendor){
                if(node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier"){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("document][createElement")!==-1&&code.indexOf("canvas)[getContext")!==-1&&code.indexOf("WEBGL_debug_renderer_info")!==-1){
                        if(code.indexOf("UNMASKED_VENDOR_WEBGL")!==-1){
                            mapObjsResult1.set(node.id.name, "getWebGLVendor");
                            setFuncsResult2.add("getWebGLVendor");
                            flag_webGLVendor = true;
                        }
                    }
                }
            }

            // navigator plugins
            if(!flag_IsPlugins){
                if(node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier"){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("navigator][plugins")!==-1&&code.indexOf("objectPlugin")!==-1){
                        mapObjsResult1.set(node.id.name, "getIsPlugins");
                        setFuncsResult2.add("getIsPlugins");
                        flag_IsPlugins = true;
                    }
                }
            }

            // plugins devicememory arr
            if(!flag_PluginsDeviceMemoryArr){
                if(node.type === "FunctionDeclaration" && node.id && node.id.type === "Identifier"){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("pluginsLength")!==-1&&code.indexOf("webGLRenderer")===-1){
                        mapObjsResult1.set(node.id.name, "getPluginsDeviceMemoryArr");
                        setFuncsResult2.add("getPluginsDeviceMemoryArr");
                        flag_PluginsDeviceMemoryArr = true;
                    }
                }
            }

            // getSensorData
            if(!flag_getSensorData){
                if(node.type === "VariableDeclarator" && node.init && node.init.type === "FunctionExpression"){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("sensor_arr")!==-1&&code.indexOf("-100")!==-1&&code.indexOf("-105")!==-1&&code.indexOf("-130")!==-1&&code.indexOf("-129")!==-1){
                        mapObjsResult1.set(node.id.name,"getSensorData");
                        setFuncsResult2.add("getSensorData");
                        flag_getSensorData = true;
                    }
                }
            }

            // mouseMoveDataSign
            if(!flag_mouseMoveDataSign){
                if(node.type==="CallExpression"&&node.callee&&node.arguments){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("startTimestamp")!==-1&&code.indexOf("deviceData")!==-1&&code.indexOf("mouseMoveData")!==-1){
                        if(node.callee.type==="CallExpression"&&node.callee.callee&&node.callee.callee.type==="Identifier"){
                            mapObjsResult1.set(node.callee.callee.name, "mouseMoveDataSign");
                            setFuncsResult2.add("mouseMoveDataSign");
                            flag_mouseMoveDataSign = true;
                        }
                    }
                }
            }

            // randomint(m,n)
            if(!flag_randomInt){
                if(node.type==="FunctionDeclaration"&& node.id && node.id.type === "Identifier"){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("'", "").replaceAll('"', "").replaceAll(" ", "");
                    if(code.indexOf("Math][round")!==-1&&code.indexOf("Math][random")!==-1&&code.indexOf("Date][now")===-1&&code.indexOf("Math][floor")===-1){
                        mapObjsResult1.set(node.id.name, "randomInt");
                        setFuncsResult2.add("randomInt");
                        flag_randomInt = true;
                    }
                }
            }
        }
    });
    // 继续查找 mouse_move_num 同组的数组其它3个变量
    var mouse_same_vars = find_mouse_same_vars(ast, mouse_same_map);
    var setVarsResult4 = new Set([...setVarsResult3, ...mouse_same_vars[1]]);
    mouse_same_vars[0].forEach((value, key) => {
        mapObjsResult1.set(key, value)
    });
    // setVarsResult3.add("sensor_arg40");
    return [mapObjsResult1, setFuncsResult2, setVarsResult4];
}

/*
查找两个变量=88888和77777
 */
function find_cookie_8877(ast){
    var result = [];
    estraverse.traverse(ast, {
        enter(node, parent){
            if(node.type==="VariableDeclarator"&&node.id&&node.id.type==="Identifier"&&node.init&&node.init.type==="ArrayExpression"&&node.init.elements){
                var eles = node.init.elements;
                if(eles.length===2){
                    var node1 = eles[0];
                    var node2 = eles[1];
                    if(node1.type==="Identifier"&&node2.type==="Identifier"){
                        if(result.length===0){
                            result = [node1.name, node2.name];
                        }
                    }
                }
            }
        }
    });
    return result;
}

/*
继续查找 mouse_move_num 同组的数组其它3个变量
mouse_same_map = {
    "mouse_track":"Ff",
    "sum_mouse_data":"",
    "pointer_click_num":""
}

result = {
   "mouse_data_fake1":"JVr",
   "mouse_data_fake3":"JVr",
   "mouse_data_fake4":"JVr",
   "pointer_click_fake1":"",
   "pointer_click_fake3":"",
   "mouse_track_fake1":"",
   "mouse_track_fake3":"",
   "mouse_track_fake4":"",
}

set(["jvr"])
 */
function find_mouse_same_vars(ast, mouse_same_map) {
    var map1 = new Map();
    var set1 = new Set();
    var mouse_track_var = mouse_same_map.get("mouse_track");
    var sum_mouse_data_var = mouse_same_map.get("sum_mouse_data");
    var pointer_click_num_var = mouse_same_map.get("pointer_click_num");
    estraverse.traverse(ast, {
        enter(node, parent) {
            if (node.type === "ArrayExpression" && node.elements && node.elements.length === 4) {
                var node1 = node.elements[0];
                var node2 = node.elements[1];
                var node3 = node.elements[2];
                var node4 = node.elements[3];
                if (node1.type === "Identifier" && node2.type === "Identifier" && node3.type === "Identifier" && node4.type === "Identifier") {
                    if (node4.name === pointer_click_num_var) {
                        map1.set(node1.name, "pointer_click_fake1");
                        map1.set(node3.name, "pointer_click_fake3");
                        set1.add("pointer_click_fake1");
                        set1.add("pointer_click_fake3");
                    }
                    if (node2.name === sum_mouse_data_var) {
                        map1.set(node1.name, "mouse_data_fake1");
                        map1.set(node3.name, "mouse_data_fake3");
                        map1.set(node4.name, "mouse_data_fake4");
                        set1.add("mouse_data_fake1");
                        set1.add("mouse_data_fake3");
                        set1.add("mouse_data_fake4");
                    }
                    if (node2.name === mouse_track_var) {
                        map1.set(node1.name, "mouse_track_fake1");
                        map1.set(node3.name, "mouse_track_fake3");
                        map1.set(node4.name, "mouse_track_fake4");
                        set1.add("mouse_track_fake1");
                        set1.add("mouse_track_fake3");
                        set1.add("mouse_track_fake4");
                    }
                }
            }
        }
    });
    return [map1, set1];
}

/*
获取二元运算固定值 map 处理固定的11个逗号表达式。如果形式变了就得改
JV = +!+[] + !+[] + !+[] + !+[] + !+[], XV = [+!+[]] + [+[]] - +!+[] - +!+[],
 */
function get_binary_func_vars(ast) {
    var result = new Map();
    estraverse.replace(ast, {
        enter(node, parent) {
            if (node.type === "SequenceExpression" && node.expressions && node.expressions.length === 11) {
                var c = 0;
                for (let i = 0; i < node.expressions.length; i++) {
                    var nodei = node.expressions[i];
                    if (nodei.type === "AssignmentExpression" && nodei.left && nodei.left.type === "Identifier" && nodei.right && (nodei.right.type === "BinaryExpression" || nodei.right.type === "UnaryExpression")) {
                        c += 1;
                    }
                }
                if (c === 11) {
                    for (let i = 0; i < node.expressions.length; i++) {
                        var nodei = node.expressions[i];
                        var right_code = escodegen.generate(nodei.right);
                        var val = eval(right_code);
                        result.set(nodei.left.name, val);
                        nodei.right = {
                            type: "Literal",
                            value: val,
                            raw: val.toString()
                        }
                    }
                }
            }
        }
    })
    return result;
}

/*
获取akamai固定的常量赋值
 */
function get_literal_vals(ast) {
    var result = new Map();
    estraverse.replace(ast, {
        enter(node, parent) {
            if (node.type === "FunctionDeclaration" && node.body && node.body.body && node.body.body.length === 1) {
                var node1 = node.body.body[0];
                if (node1.type === "ExpressionStatement" && node1.expression) {
                    var node2 = node1.expression;
                    if (node2.type === "SequenceExpression" && node2.expressions && node2.expressions.length >= 300) {
                        var code = escodegen.generate(node2);
                        console.log(code);
                        console.log(node2.expressions.length);
                        for (let i = 0; i < node2.expressions.length; i++) {
                            var nodei = node2.expressions[i];
                            result.set(nodei.left.name, nodei.right.value);
                        }
                    }
                }
            }

        }
    })
    return result;
}

/*
获取大量变量定义在一行的变量 akamai是有2个巨长变量定义。这里是获取的第二个最长的那个。
大量变量定义长度范围 [minL, maxL]
 */
function get_vars_def(ast, minL, maxL) {
    var result = "";
    estraverse.traverse(ast, {
        enter(node, paret) {
            if (node.type === "VariableDeclaration" && node.declarations && node.declarations.length >= minL && node.declarations.length<=maxL) {
                var code = escodegen.generate(node);
                var c = 0;
                console.log(code);
                console.log(node.declarations.length);
                for (let i = 0; i < node.declarations.length; i++) {
                    var nodei = node.declarations[i];
                    if (nodei.id && nodei.id.type === "Identifier" && nodei.type === "VariableDeclarator" && nodei.init === null) {
                        c += 1;
                    }
                }
                if (node.declarations.length === c) {
                    // return code;
                    result = code;
                }
            }
        }
    })
    return result;
}

/*
查询能够处理的循环 switch 语句，
 */
function find_switch_case_for(ast) {
    estraverse.replace(ast, {
        leave(node, parent) {
            if ((node.type === "ForStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement") && node.body && node.body.type === "BlockStatement" && node.body.body && node.body.body.length === 1) {
                var node1 = node.body.body[0];
                if (node1.type === "SwitchStatement" && node1.discriminant && node1.discriminant.type === "Identifier") {
                    var dis = node1.discriminant.name;
                    var sort_values = base_ast.switchcase_tool(node, dis);
                    var sorted_values = getadjacencyList(sort_values);
                    var new_code = resort_switchcase_tool2(node, dis, sorted_values);
                    console.log("dis:", dis);
                    var new_ast = esprima.parse(new_code);

                    return new_ast.body[0].body.body[0];
                }
            }
        }
    })
}

/*
循环处理set集合中的函数，重命名函数内部变量
 */
function funcs_rename_var(ast, set_funcs) {
    estraverse.replace(ast, {
        enter(node, parent) {
            if (node.type === "VariableDeclarator" && node.id && node.init && node.init.type === "FunctionExpression") {
                var func_name = node.id.name;
                if (set_funcs.has(func_name)) {
                    base_ast.rename_func_vars(node, func_name);
                }
            }
            if (node.type === "FunctionDeclaration" && node.id) {
                var func_name = node.id.name;
                if (set_funcs.has(func_name)) {
                    base_ast.rename_func_vars(node, func_name);
                }
            }
        }
    })
}


/*
根据集合中的变量名 获取他们的初始化的位置并翻译成代码
 */
function getInitCodeForVarname(ast, set_vars) {
    var code = "";
    estraverse.traverse(ast, {
        enter(node, parent) {
            if (node.type === "VariableDeclaration" && node.declarations && node.declarations.length === 1) {
                var node1 = node.declarations[0];
                if (node1.type === "VariableDeclarator" && node1.id && node1.id.type === "Identifier") {
                    var name = node1.id.name;
                    if (set_vars.has(name)) {
                        code += escodegen.generate(node) + "\n";
                    }
                }
            }
        }
    });
    code += `g_win.window.bmak = {
    "startTs": getDateNow(),
    "firstLoad":true
};\n`;
    return code;
}

/*
查找函数--返回一个字符串数组的函数
 */
function findFuncForConstReturn(ast){
    var result = new Map();
    estraverse.traverse(ast, {
        enter(node, parent){
            if(node.type==="FunctionDeclaration"&&node.id&&node.id.type==="Identifier"&&node.body&&node.body.type==="BlockStatement"&&node.params.length===0){
                if(node.body.body&&node.body.body.length===3){
                    var node1 = node.body.body[0];
                    var node2 = node.body.body[1];
                    var node3 = node.body.body[2];
                    if(node1.type==="VariableDeclaration"&&node2.type==="ExpressionStatement"&&node3.type==="ReturnStatement"){
                        if(node1.declarations&&node1.declarations.length===1&&node1.declarations[0].type==="VariableDeclarator"){
                            if(node1.declarations[0].id&&node1.declarations[0].id.name.indexOf("ConstArr")!==-1){
                                var code = escodegen.generate(node);
                                result.set(node.id.name, code);

                            }
                        }
                    }
                }
            }
        }
    });
    return result;
}

/*
查找解密数组子函数直接返回的函数
 */
function findFuncForConstReturnStep2(ast, con_map){
    var result = new Map();
    estraverse.traverse(ast,{
        enter(node, parent){
            if(node.type==="FunctionDeclaration"&&node.id&&node.id.type==="Identifier"&&node.params&&node.params.length===1&&node.body&&node.body.type==="BlockStatement"){
                if(node.body.body&&node.body.body.length===1&&node.body.body[0].type==="ReturnStatement"){
                    var noder = node.body.body[0];
                    if(noder.argument&&noder.argument.object&&noder.argument.object.type==="CallExpression"&&noder.argument.object.callee&&noder.argument.object.callee.type==="Identifier"){
                        var f_name = noder.argument.object.callee.name;
                        if(con_map.has(f_name)){
                            var name = node.id.name;
                            var code = escodegen.generate(node);
                            result.set(name, code);
                        }
                    }
                }
            }
        }
    });
    return result;
}

/*
replace 替换掉解密的子函数到使用地方
 */
function replaceFuncForConstReturnStep3(ast, con_map, code){
    var result = new Map();
    estraverse.replace(ast,{
        enter(node, parent){
            if(node.type==="MemberExpression"&&node.object&&node.object.callee&&node.object.callee.type==="Identifier"&&node.object.type==="CallExpression"&&node.property&&node.property.type==="CallExpression"){
                var nodep = node.property;
                if(nodep.callee&&nodep.callee.type==="Identifier"&&con_map.has(nodep.callee.name)&&nodep.arguments&&nodep.arguments.length===1&&nodep.arguments[0].type==="Literal"){
                    eval(code);
                    var val = eval(escodegen.generate(nodep));
                    node.property = {
                        type:"Literal",
                        value:val,
                        raw:val.toString()
                    }
                    if(!result.has(node.object.callee.name)){
                        result.set(node.object.callee.name, 1);
                    }else{
                        result.set(node.object.callee.name, result.get(node.object.callee.name)+1);
                    }

                }
            }
        }
    });
    return result;
}

/*
增加hook substr代码，返回正确的结果
s = YvAVvnNNgz
a = 217487
b = 10
 */
function addHookSubstr(ast, s, a, b, d){
    estraverse.replace(ast,{
        enter(node, parent){
            if(node.type==="ReturnStatement"&&node.argument&&node.argument.type==="CallExpression"&&node.argument.callee&&node.argument.callee.type==="MemberExpression"){
                if(node.argument.callee.property&&node.argument.callee.property.type==="Identifier"&&node.argument.callee.property.name==="substr"){
                    var arga = node.argument.callee.object.name;
                    var argb = node.argument.arguments[0].name;
                    var argc = node.argument.arguments[1].name;
                    var newCode = `function a(){if(${arga}.substring(0,21)==="function ${s}()"&&${argb}===${a}&&${argc}===${b}){
                            return "${d}";
                        }}`;
                    console.log(newCode);
                    const index = parent.body.indexOf(node);
                    // var newCode = `g_de_map.set('${de_func_name}.' + ${dec_func1}, ${return_var});`
                    var newast = esprima.parse(newCode);
                    var newNode = newast.body[0].body.body[0];
                    parent.body.splice(index, 0, newNode);
                }
            }
        }
    })
}

/*
修改函数签名值
 */
function changeSignFunc(ast,trait, signNum){
    estraverse.replace(ast,{
        leave(node, parent){
            if(node.type==="ReturnStatement"&&node.argument&&node.argument.type==="CallExpression"){

                if(node.argument.arguments&&node.argument.arguments.length===2&&node.argument.arguments[1].type==="Literal"&&node.argument.arguments[1].value===trait){
                    var code = escodegen.generate(node);
                    code = code.replaceAll("return", "var result =");
                    code += "result = "+signNum+"; return result;";
                    const index = parent.body.indexOf(node);
                    var newCode =  `function a(){`+code+"}";
                    var newast = esprima.parse(newCode);
                    // var newNode = newast.body[0].body.body[0];
                    // for(var i=0;i<newast.body[0].body.body.length;i++){
                    //     var newNode = newast.body[0].body.body[i];
                    //     parent.body.splice(index, 0, newNode);
                    // }
                    // parent.body = newast.body[0].body;
                    parent.body.splice(index, 0, ...newast.body[0].body.body);
                    parent.body.splice(newast.body[0].body.body.length, 1);
                    // return estraverse.VisitorOption.Remove;
                }
            }
        }
    })
}

/*
将V2.5版本的map 解密字符串替换到引用的位置
@param {Map} map_de
 */
function replaceDeStrV2_5(ast, map_de){
    estraverse.replace(ast, {
        enter(node, parent){
            if(node.type==="CallExpression"&&node.callee&&node.arguments){
                if(node.callee.object&&node.callee.object.type==="CallExpression"&&node.callee.property&&node.callee.property.type==="Literal"){
                    if(node.callee.object.callee&&node.callee.object.callee.type==="Identifier"){
                        var key = node.callee.object.callee.name+"."+node.callee.property.value;
                        if(map_de.hasOwnProperty(key)){
                            return {
                                type:esprima.Syntax.Literal,
                                value:map_de[key],
                                raw:map_de[key].toString()
                            }
                        }
                    }
                }
                if(node.callee.type==="MemberExpression"&&node.callee.object&&node.callee.object.type==="MemberExpression"&&node.callee.property){
                    if(node.callee.property.type==="Identifier"&&node.callee.object.object&&node.callee.object.object.type==="CallExpression"&&(node.callee.property.name==="apply"||node.callee.property.name==="call")){
                        if(node.callee.object.property&&node.callee.object.property.type==="Literal"&&node.callee.object.object.callee){
                            if(node.callee.object.object.callee.type==="Identifier"){
                                var key = node.callee.object.object.callee.name+"." + node.callee.object.property.value;
                                if(map_de.hasOwnProperty(key)){
                                    return {
                                        type:esprima.Syntax.Literal,
                                        value:map_de[key],
                                        raw:map_de[key].toString()
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // if(node.type==="CallExpression"&&ode.callee)
        }
    })
}

/*
替换掉typeof 语句
typeof jV()['IB']
 */
function replaceTypeof(ast, map_de){
    estraverse.replace(ast,{
        enter(node, parent){
            if(node.type==="UnaryExpression"&&node.argument&&node.operator==="typeof"&&node.argument.type==="MemberExpression"){
                if(node.argument.object&&node.argument.object.type==="CallExpression"&&node.argument.property&&node.argument.property.type==="Literal"){
                    if(node.argument.object.callee&&node.argument.object.callee.type==="Identifier"){
                        var key = node.argument.object.callee.name+"."+node.argument.property.value;
                        if(map_de.hasOwnProperty(key)){
                            return {
                                type:esprima.Syntax.Literal,
                                value:"function",
                                raw:"function".toString()
                            }
                        }
                    }
                }
            }
        }
    })
}

/*
把简单函数执行一次，有结果的就替换掉
 */
function exec_sample_func(ast, sample_map){
    var c = 0;
    estraverse.replace(ast,{
        leave(node, parent){
            if(node.type==="CallExpression"&&node.callee&&node.arguments&&node.arguments.length>0&&sample_map.has(node.callee.name)){
                // var flag = false;
                var i=0;
                for(i;i<node.arguments.length;i++){
                    var nodei = node.arguments[i];
                    if(nodei.type==="Literal"||(nodei.type==="Identifier"&&nodei.name==="undefined"||nodei.type==="ArrayExpression"&&nodei.elements.length===0)){
                        continue
                    }
                    break
                }
                var code = escodegen.generate(node);
                // console.log(code, "i="+i);
                // console.log("func:"+node.callee.name);
                // escodegen.generate(ast);
                // var code2 = escodegen.generate(parent);
                // console.log("parent:"+code2);
                // es_tool.save_ast_to_file(ast, `./aaa/${c}.js`);
                // c += 1;
                if(i===node.arguments.length){
                    // var code = escodegen.generate(node);
                    console.log(code);
                    var val = eval(code);
                    console.log("val:"+val);
                    if(typeof val ==="number"){
                        if(val<0){
                            return {
                                type:"UnaryExpression",
                                operator:"-",
                                argument:{
                                    type:"Literal",
                                    value:-val,
                                    raw:(-val).toString()
                                }
                            }
                        }
                    }
                    if(typeof val===undefined){
                        return {
                            type:esprima.Syntax.Identifier,
                            value:"undefined",
                        }
                    }
                    return {
                        type:esprima.Syntax.Literal,
                        value:val,
                        raw:val.toString()
                    }
                }
            }
        }
    })
}

module.exports = {
    resort_switchcase_tool2,
    getadjacencyList,
    de_str1,
    insert_hook_destr,
    insert_hook_destrV2_5,
    find_andhook_sensor_arr,
    find_global_vars,
    get_binary_func_vars,
    get_literal_vals,
    get_vars_def,
    find_switch_case_for,
    funcs_rename_var,
    getInitCodeForVarname,
    findFuncForConstReturn,
    findFuncForConstReturnStep2,
    replaceFuncForConstReturnStep3,
    addHookSubstr,
    changeSignFunc,
    replaceDeStrV2_5,
    replaceTypeof,
    exec_sample_func
}
